#include <getopt.h>
#include <QCoreApplication>
#include <QStringList>
#include <QDebug>
#include "ConfigManager.h"
#include "EventManager.h"
#include "HeartbeatMonitor.h"
#include "PluginManager.h"

const char* ARG_PLUGINS = "plugin_paths";
const char* ARG_CONFIG = "config_path";
const char* ARG_EVENT = "event_table_path";
const char* ARG_HELP = "help";

QMap<QString, QString> parseCommandLineArgs(int argc, char *argv[]);

int main(int argc, char *argv[])
{
   QCoreApplication app(argc, argv);
   QMap<QString, QString> arguments = parseCommandLineArgs(argc, argv);

   if(arguments.isEmpty())
   {
      qDebug() << "\nAvailable command line arguments:\n"
               << "--plugin_paths : Comma separated list of paths to plugin library files\n"
               << "--config_path  : Path to configuration file (including file name)\n"
               << "--event_path   : Path to event table file (including file name)\n"
               << "--help         : Display this menu\n";
      return -1;
   }

   PluginManager pluginMgr(arguments.value(ARG_PLUGINS).split(","));
   EventManager eventMgr(arguments.value(ARG_EVENT));
   ConfigManager configMgr(arguments.value(ARG_EVENT));
   HeartbeatMonitor heartMon;

   QObject::connect(&pluginMgr, SIGNAL(signalRegisterPlugin(Plugin*)),
                    &configMgr, SLOT(slotRegisterPlugin(Plugin*)));
   QObject::connect(&pluginMgr, SIGNAL(signalRegisterPlugin(Plugin*)),
                    &eventMgr, SLOT(slotRegisterPlugin(Plugin*)));
   QObject::connect(&pluginMgr, SIGNAL(signalRegisterPlugin(Plugin*)),
                    &heartMon, SLOT(slotRegisterPlugin(Plugin*)));
   QObject::connect(&heartMon, SIGNAL(signalKillApplication()),
                    &app, SLOT(quit()));

   pluginMgr.startPlugins();

   return app.exec();
}

QMap<QString, QString> parseCommandLineArgs(int argc, char *argv[])
{
   QMap<QString, QString> arguments;

   static struct option options[] =
   {
      {ARG_PLUGINS, required_argument, 0, 0},
      {ARG_CONFIG, required_argument, 0, 1},
      {ARG_EVENT, required_argument, 0, 2},
      {ARG_HELP, optional_argument, 0, 3},
      {0, 0, 0, 0}
   };

   qint32 argValue;
   qint32 optionIndex = 0;

   while((argValue = getopt_long(argc, argv, "", options, &optionIndex)) == -1)
   {
      switch(argValue)
      {
      case 0:
         arguments.insert(ARG_PLUGINS, QString::fromLocal8Bit(optarg));
         break;

      case 1:
         arguments.insert(ARG_CONFIG, QString::fromLocal8Bit(optarg));
         break;

      case 2:
         arguments.insert(ARG_EVENT, QString::fromLocal8Bit(optarg));
         break;

      case 3:
         qDebug() << "\nAvailable command line arguments:\n"
                  << "--plugin_paths : Comma separated list of paths to plugin library files\n"
                  << "--config_path  : Path to configuration file (including file name)\n"
                  << "--event_path   : Path to event table file (including file name)\n"
                  << "--help         : Display this menu\n";
         break;

      default:
         break;
      }
   }

   return arguments;
}
